How a language with one thread still gets concurrent-feeling behavior.
JavaScript executes on a single thread — only one line of your code runs at any instant. But 'single-threaded' doesn't mean the environment around it is. Browsers hand off networking, timers, and rendering to separate OS-level threads, and Node.js runs I/O through libuv's thread pool, so the parts of your program that feel 'concurrent' (a fetch resolving while a click handler fires) are actually the runtime coordinating work outside the JS thread and feeding results back through the event loop.
True parallel execution of your own JavaScript needs an explicit mechanism: Web Workers in the browser, worker_threads in Node. Each worker gets its own thread, its own memory, and its own event loop, and they don't share objects directly — they communicate by copying data through postMessage (or, for large binary data, transferring ownership via ArrayBuffer). That isolation is deliberate: it avoids the race conditions that come with shared-memory threading, at the cost of needing to serialize everything you send across.
What you'll walk away knowing